package com.zhz.system.biz;

import com.google.common.collect.Sets;
import com.zhz.common.enums.BizResponseEnum;
import com.zhz.common.utils.ConvertUtils;
import com.zhz.model.system.contract.dto.PermissionDTO;
import com.zhz.model.system.contract.param.PermissionQueryParam;
import com.zhz.system.contract.request.*;
import com.zhz.system.contract.response.PermissionFindAllResponse;
import com.zhz.system.contract.response.PermissionFindByIdResponse;
import com.zhz.system.repository.service.PermissionService;
import com.zhz.system.strategy.PermissionTypeOperator;
import com.zhz.system.strategy.PermissionTypeOperatorRouter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 权限业务处理
 *
 * @author zhouhengzhe
 * @date 2023/3/30
 */
@Service
public class PermissionBizService {

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private PermissionTypeOperatorRouter permissionTypeOperatorRouter;

    /**
     * 保存权限
     *
     * @param permissionSaveRequest 权限保存请求
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(PermissionSaveRequest permissionSaveRequest) {
        PermissionDTO permissionDTO = ConvertUtils.sourceToTarget(permissionSaveRequest, PermissionDTO.class);
        //3.保存权限
        permissionService.save(permissionDTO);
        //2.根据类型构造不同的资源对象（菜单，按钮，api）
        PermissionTypeOperator permissionTypeOperator = permissionTypeOperatorRouter.route(permissionDTO.getType());
        permissionTypeOperator.add(permissionSaveRequest, permissionDTO.getId());

    }

    /**
     * 修改权限
     *
     * @param permissionUpdateRequest 权限修改请求
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(PermissionUpdateRequest permissionUpdateRequest) {
        PermissionDTO permissionDTO = getPermissionDTO(permissionUpdateRequest.getId());
        //3.保存权限
        permissionDTO.setCode(permissionUpdateRequest.getCode())
                .setName(permissionUpdateRequest.getName())
                .setDescription(permissionUpdateRequest.getDescription())
                .setEnVisible(permissionUpdateRequest.getEnVisible());
        permissionService.update(permissionDTO);
        //2.根据类型构造不同的资源对象（菜单，按钮，api）
        PermissionTypeOperator permissionTypeOperator = permissionTypeOperatorRouter.route(permissionDTO.getType());
        permissionTypeOperator.update(permissionUpdateRequest, permissionDTO.getId());

    }

    /**
     * 根据id获取权限
     *
     * @param id 权限id
     * @return
     */
    private PermissionDTO getPermissionDTO(String id) {
        PermissionDTO permissionDTO = permissionService.getOne(PermissionQueryParam.builder().id(id).build());
        BizResponseEnum.PERMISSION_NOT_EXIST.assertNotNullWithMsg(permissionDTO, String.format("当前的权限ID为：%s", id));
        return permissionDTO;
    }

    /**
     * 4.查询全部
     * type      : 查询全部权限列表type：0：菜单 + 按钮（权限点） 1：菜单2：按钮（权限点）3：API接口
     * enVisible : 0：查询所有saas平台的最高权限，1：查询企业的权限
     * pid ：父id
     *
     * @param permissionFindAllRequest 权限查询请求
     * @return
     */
    public PermissionFindAllResponse findAll(PermissionFindAllRequest permissionFindAllRequest) {
        Set<Integer> types = Sets.newHashSet();
        //根据类型 type
        Integer type = permissionFindAllRequest.getType();
        if (Objects.nonNull(type)) {
            if (type == 0) {
                types.add(1);
                types.add(2);
            } else {
                types.add(type);
            }
        }
        PermissionQueryParam permissionQueryParam = PermissionQueryParam
                .builder()
                .enVisible(permissionFindAllRequest.getEnVisible())
                .pid(permissionFindAllRequest.getPid())
                .typeSet(types)
                .build();
        List<PermissionDTO> permissionList = permissionService.list(permissionQueryParam);
        List<PermissionFindAllResponse.PermissionFindAllInfo> permissionFindAllInfos = permissionList
                .stream()
                .map(permissionDTO ->
                        PermissionFindAllResponse.PermissionFindAllInfo
                                .builder()
                                .id(permissionDTO.getId())
                                .description(permissionDTO.getDescription())
                                .name(permissionDTO.getName())
                                .type(permissionDTO.getType())
                                .pid(permissionDTO.getPid())
                                .code(permissionDTO.getCode())
                                .enVisible(permissionDTO.getEnVisible())
                                .build())
                .collect(Collectors.toList());
        return PermissionFindAllResponse
                .builder()
                .permissionList(permissionFindAllInfos)
                .build();
    }

    /**
     * 根据ID查询权限
     *
     * @param permissionFindByIdRequest 权限查询请求
     * @return
     */
    public PermissionFindByIdResponse findById(PermissionFindByIdRequest permissionFindByIdRequest) {
        PermissionDTO permissionDTO = getPermissionDTO(permissionFindByIdRequest.getId());
        PermissionFindByIdResponse permissionFindByIdResponse = new PermissionFindByIdResponse();
        //2.根据类型构造不同的资源对象（菜单，按钮，api）
        PermissionTypeOperator permissionTypeOperator = permissionTypeOperatorRouter.route(permissionDTO.getType());
        permissionFindByIdResponse = permissionTypeOperator.findById(permissionFindByIdResponse, permissionDTO.getId());
        permissionFindByIdResponse.setName(permissionDTO.getName())
                .setId(permissionDTO.getId())
                .setCode(permissionDTO.getCode())
                .setDescription(permissionDTO.getDescription())
                .setEnVisible(permissionDTO.getEnVisible())
                .setType(permissionDTO.getType())
                .setPid(permissionDTO.getPid());
        return permissionFindByIdResponse;
    }

    /**
     * 根据id删除权限
     * 1.删除权限
     * 2.删除权限对应的资源
     *
     * @param permissionDeleteRequest 权限删除请求
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(PermissionDeleteByIdRequest permissionDeleteRequest) {
        //1.通过传递的权限id查询权限
        PermissionDTO permissionDTO = getPermissionDTO(permissionDeleteRequest.getId());
        permissionService.delete(permissionDTO.getId());
        //2.根据类型构造不同的资源对象（菜单，按钮，api）
        PermissionTypeOperator permissionTypeOperator = permissionTypeOperatorRouter.route(permissionDTO.getType());
        permissionTypeOperator.deleteById(permissionDTO.getId());
    }
}
